/*
 * HSM Proxy Project.
 * Copyright (C) 2013 FedICT.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License version
 * 3.0 as published by the Free Software Foundation.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, see 
 * http://www.gnu.org/licenses/.
 */

package test.integ.be.fedict.hsm.rest.security;

import java.security.Principal;
import java.util.Map;
import java.util.Set;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

import be.fedict.hsm.model.security.JBossRolesGroup;
import be.fedict.hsm.model.security.SimplePrincipal;

public class SecurityTestLoginModule implements LoginModule {

	private Subject subject;
	private CallbackHandler callbackHandler;
	private String authenticatedUsername;

	@Override
	public void initialize(Subject subject, CallbackHandler callbackHandler,
			Map<String, ?> sharedState, Map<String, ?> options) {
		this.subject = subject;
		this.callbackHandler = callbackHandler;
	}

	@Override
	public boolean login() throws LoginException {
		NameCallback nameCallback = new NameCallback("username");
		PasswordCallback passwordCallback = new PasswordCallback("password",
				false);
		Callback[] callbacks = new Callback[] { nameCallback, passwordCallback };
		try {
			this.callbackHandler.handle(callbacks);
		} catch (Exception e) {
			throw new LoginException(e.getMessage());
		}
		String username = nameCallback.getName();
		String password = new String(passwordCallback.getPassword());
		if (false == "username".equals(username)) {
			throw new LoginException("invalid user");
		}
		if (false == "password".equals(password)) {
			throw new LoginException("invalid password");
		}
		this.authenticatedUsername = username;
		return true;
	}

	@Override
	public boolean commit() throws LoginException {
		if (null != this.authenticatedUsername) {
			Set<Principal> principals = this.subject.getPrincipals();
			principals.add(new SimplePrincipal(this.authenticatedUsername));
			JBossRolesGroup rolesGroup = new JBossRolesGroup();
			rolesGroup.addMember(new SimplePrincipal("myrole"));
			principals.add(rolesGroup);
			reset();
		}
		return true;
	}

	private void reset() {
		this.authenticatedUsername = null;
	}

	@Override
	public boolean abort() throws LoginException {
		logout();
		return true;
	}

	@Override
	public boolean logout() throws LoginException {
		reset();
		this.subject.getPrincipals().clear();
		return true;
	}
}